﻿using System.Collections.Generic;
using Core;
using UnityEngine;

namespace Core
{
    public interface IPanelCoverHelper : IHelperTag
    {
        void HidePanel(GameObject panelGo);
        void ShowPanel(GameObject panelGo);
        void CoverPanel(PanelLayerType layer, Dictionary<PanelLayerType, Stack<PanelStackData>> stacks, Dictionary<string, BasePanel> opens);
        void PopPanel(PanelLayerType layer, Dictionary<PanelLayerType, Stack<PanelStackData>> stacks, Dictionary<string, BasePanel> opens);
    }

    internal class PanelCoverHelper : Helper, IPanelCoverHelper
    {
        Dictionary<PanelLayerType, Stack<Stack<PanelStackData>>> stackDic = new Dictionary<PanelLayerType, Stack<Stack<PanelStackData>>>();

        public void CoverPanel(PanelLayerType layer, Dictionary<PanelLayerType, Stack<PanelStackData>> stacks, Dictionary<string, BasePanel> opens)
        {
            Stack<PanelStackData> stackData = null;
            if (!stacks.TryGetValue(layer, out stackData))
                return;

            if (stackData.Count == 0)
                return;

            var data = stackData.Peek();
            var panel = data.panel;
            Stack<Stack<PanelStackData>> stackPanel = null;
            if (!stackDic.TryGetValue(panel.panelLayer, out stackPanel))
            {
                stackPanel = new Stack<Stack<PanelStackData>>();
                stackDic[panel.panelLayer] = stackPanel;
            }

            var curStack = new Stack<PanelStackData>();
            while (stackData.Count > 0)
            {
                var curData = stackData.Pop();
                curData.panel.panelState = PanelState.Freeze;
                curData.panel._Freeze();

                // 隐藏界面
                var panelGo = curData.panel.gameObject;
                HidePanel(panelGo);

                opens.Remove(curData.panel.panelPath);
                curStack.Push(curData);
            }

            stackPanel.Push(curStack);
        }

        public void PopPanel(PanelLayerType layer, Dictionary<PanelLayerType, Stack<PanelStackData>> stacks, Dictionary<string, BasePanel> opens)
        {
            Stack<PanelStackData> stackData = null;
            if (!stacks.TryGetValue(layer, out stackData))
                return;

            Stack<Stack<PanelStackData>> stackPanel = null;
            if (!stackDic.TryGetValue(layer, out stackPanel))
                return;

            if (stackPanel.Count == 0)
                return;

            var curStack = stackPanel.Pop();
            while (curStack.Count > 0)
            {
                var curData = curStack.Pop();
                curData.panel.panelState = PanelState.Show;
                curData.panel._UnFreeze();

                // 显示界面
                var panelGo = curData.panel.gameObject;
                ShowPanel(panelGo);

                opens.Add(curData.panel.panelPath, curData.panel);
                stackData.Push(curData);
            }
        }

        public void HidePanel(GameObject panelGo)
        {
            // 隐藏界面
            var group = panelGo.GetComponent<CanvasGroup>();
            if (group == null)
                group = panelGo.AddComponent<CanvasGroup>();
            group.alpha = 0;
        }

        public void ShowPanel(GameObject panelGo)
        {
            var group = panelGo.GetComponent<CanvasGroup>();
            if (group == null)
                group = panelGo.AddComponent<CanvasGroup>();
            group.alpha = 1;
        }
    }
}